package units;

import java.util.*;

import pheromoneMap.PheromoneMap;
import pheromoneMap.PheromoneType;
import base.PheromoneMain;
import base.ProxyBot;
import base.UnitType;
import base.ResearchType;
import base.WargusUnit;

public class QueenUnit extends AntUnit {
	
	 ArrayList<WargusUnit> m_units;
	
	static final double MIN_WOOD = 2000.0;
	static final double MIN_GOLD = 2000.0;
	int m_peon_count;
	int m_grunt_count;
	int m_range_count; 
	int barracksCount;
	int towerCount;
	
	int blacksmithCount;
	int lumbermillCount;
	
	private static ArrayList<ResearchType> m_research = new ArrayList<ResearchType>();
	
	public QueenUnit(ProxyBot proxyBot, PheromoneMap pheromoneMap, WargusUnit wargusUnit) {
		super( proxyBot, pheromoneMap, wargusUnit );
	}
	
	public QueenUnit(ProxyBot proxyBot, PheromoneMap pheromoneMap, WargusUnit wargusUnit, ArrayList<WargusUnit> m_units) {
		super( proxyBot, pheromoneMap, wargusUnit );
		this.m_units = m_units;
		
	}
	
	public void updateState() {
		int width = unit.getTypeEnum().getUnitWidth();
		int height = unit.getTypeEnum().getUnitHeight();
		//int map_x = unit.getLocX() + ( width / 2);
		//int map_y = unit.getLocY() + ( height / 2);
		
		//if(unit.getUnitStatus() == "training" && unit.getStatus()[0] == 0)
			//unit.setUnitStatus("idle");
		
		//System.out.println("QueenUnit: " + blacksmithCount + "," + lumbermillCount);
		for (WargusUnit unit : m_units)
		{
			if(unit.getTypeEnum() == UnitType.HUMAN_TOWN_HALL
					|| unit.getTypeEnum() == UnitType.HUMAN_KEEP
					|| unit.getTypeEnum() == UnitType.HUMAN_CASTLE)
			{
				double woodDeficiency = Math.pow( MIN_WOOD / (proxyBot.getWood()+1), 1.2 );
				double goldDeficiency = Math.pow( MIN_GOLD / (proxyBot.getGold()+1), 1.2 );
				double supplyDeficiency = Math.pow( (proxyBot.getDemand() / (proxyBot.getFood())) + 1, 1.2);
				double barracksDeficiency = Math.max(0, (1.0 - barracksCount));//Math.pow(Math.abs((barracksCount - m_peon_count / 20.0)) + 1, 1.0);
				double towerDeficiency = Math.pow(Math.abs((towerCount - m_peon_count / 20.0)) + 1, 1.0);
				
				double blacksmithDeficiency = Math.max(0, (1.0 - blacksmithCount));
				double lumbermillDeficiency = Math.max(0, (1.0 - lumbermillCount));
				//System.out.println("QueenUnit: lumbermillDeficiency - " + lumbermillDeficiency);
				//System.out.println("QueenUnit: barracksDeficiency - " + barracksDeficiency);
				pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.TO_HOME, 10000, width, height);
				
				//if(proxyBot.getWood() < MIN_WOOD)
					pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.NEED_WOOD, 5.0 * woodDeficiency, width, height);
				
				//if(proxyBot.getGold() < MIN_GOLD)
					pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.NEED_GOLD, 5.0 * goldDeficiency, width, height);
				
				//if(proxyBot.getFood() <= m_peon_count)
					pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.NEED_FARM, 60.0 * supplyDeficiency, width, height);
			
				//if(barracksCount <= m_peon_count / 10)
					pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.NEED_BARRACKS, 60.0 * barracksDeficiency, width, height);
					
				if (this.barracksCount > 0) {	
					pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.NEED_BLACKSMITH, 60.0 * blacksmithDeficiency, width, height);
				}
					pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.NEED_LUMBERMILL, 60.0 * lumbermillDeficiency, width, height);
					
				if (this.lumbermillCount > 0) {
					pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.NEED_TOWER, 60.0 * towerDeficiency, width, height);
				}
			}
		}
		
		/*
		pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.TO_HOME, 100, width, height);
		
		if(proxyBot.getWood() < min_wood)
			pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.NEED_WOOD, (20.0 * min_wood / (proxyBot.getWood()+1)), width, height);
		
		
		if(proxyBot.getGold() < min_gold)
			pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.NEED_GOLD, (20.0 * min_gold / (proxyBot.getGold()+1)), width, height);
		
		if(proxyBot.getFood() <= m_peon_count)
			pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.NEED_FARM, 20.0, width, height);
	
		if(barracksCount <= m_peon_count / 10)
			pheromoneMap.placeAttractionSquare(unit.getLocX(), unit.getLocY(), PheromoneType.NEED_BARRACK, 20.0, width, height);
		*/
		
	}

	public void move() {

		for (WargusUnit unit : m_units)
		{
			//System.out.println(barracksCount - m_peon_count / 15.0 > 0.0);
			
			if((unit.getTypeEnum() == UnitType.HUMAN_TOWN_HALL
					|| unit.getTypeEnum() == UnitType.HUMAN_KEEP
					|| unit.getTypeEnum() == UnitType.HUMAN_CASTLE) 
					&& unit.getStatus()[0] == 0 && proxyBot.getDemand() < proxyBot.getFood() 
					&& proxyBot.getGold() > UnitType.HUMAN_PEASANT.getGoldCost()  
					&& m_peon_count < ((m_grunt_count + m_range_count) / 2.0 + 10) && m_peon_count <= 40.0)
					//&& (Math.min(0, (blacksmithCount - 1.0)) * (blacksmithCount - m_peon_count / 15.0)) < 1.0 
					//&&  (Math.min(0, (lumbermillCount - 1.0)) * (lumbermillCount - m_peon_count / 15.0)) < 1.0)
			{
				System.out.println("Queen Unit: Offensive Count - " + m_peon_count + "," + (m_grunt_count + m_range_count));
				proxyBot.train(unit.getUnitID(), UnitType.HUMAN_PEASANT.getUnitTypeNum());
				//unit.setUnitStatus("training");
			}
			
			else if(unit.getTypeEnum() == UnitType.HUMAN_BARRACKS && unit.getStatus()[0] == 0 && proxyBot.getDemand() < proxyBot.getFood() &&  proxyBot.getGold() > UnitType.HUMAN_FOOTMAN.getGoldCost() && (m_grunt_count + m_range_count) <= 2.0 * (m_peon_count - 10))
			{
				
				
				double train_new = PheromoneMain.m_gen.nextDouble();
				
				if(train_new < 0.5)
					proxyBot.train(unit.getUnitID(), UnitType.HUMAN_FOOTMAN.getUnitTypeNum());
				else if(lumbermillCount > 0)
					proxyBot.train(unit.getUnitID(), UnitType.HUMAN_ARCHER.getUnitTypeNum());
			}
			
			else if(unit.getTypeEnum() == UnitType.HUMAN_WATCH_TOWER
					&& unit.getStatus()[0] == 0
					&& proxyBot.getGold() > UnitType.HUMAN_GUARD_TOWER.getGoldCost()
					&& proxyBot.getWood() > UnitType.HUMAN_GUARD_TOWER.getWoodCost()
					&& this.lumbermillCount > 0) {
			
					proxyBot.upgrade(unit.getUnitID(), UnitType.HUMAN_GUARD_TOWER.getUnitTypeNum());
					//System.out.println("QueenUnit: move - Upgrade the tower!");
			}
			else if (unit.getTypeEnum() == UnitType.HUMAN_BLACKSMITH
					|| unit.getTypeEnum() == UnitType.ORC_BLACKSMITH) {
				
				 if(unit.getStatus()[0] == 0 
							&& m_research.contains(ResearchType.HUMAN_SHIELD_1) == false 
							&& proxyBot.getGold() > ResearchType.HUMAN_SHIELD_1.getGoldCost()
							&& proxyBot.getWood() > ResearchType.HUMAN_SHIELD_1.getWoodCost()
							&& this.m_grunt_count >= 1)
				{
							proxyBot.research(unit.getUnitID(), ResearchType.HUMAN_SHIELD_1.getIdNum());
							m_research.add(ResearchType.HUMAN_SHIELD_1);
							
				}
				
				 
			    else if(unit.getStatus()[0] == 0 
					&& m_research.contains(ResearchType.HUMAN_SWORD_1) == false 
					&& proxyBot.getGold() > ResearchType.HUMAN_SWORD_1.getGoldCost()
					&& proxyBot.getWood() > ResearchType.HUMAN_SWORD_1.getWoodCost()
					&& this.m_grunt_count >= 1)
				{
					proxyBot.research(unit.getUnitID(), ResearchType.HUMAN_SWORD_1.getIdNum());
					m_research.add(ResearchType.HUMAN_SWORD_1);
					
				}
				
				 else if(unit.getStatus()[0] == 0 
							&& m_research.contains(ResearchType.HUMAN_SHIELD_2) == false
							&& m_research.contains(ResearchType.HUMAN_SHIELD_1)
							&& proxyBot.getGold() > ResearchType.HUMAN_SHIELD_2.getGoldCost()
							&& proxyBot.getWood() > ResearchType.HUMAN_SHIELD_2.getWoodCost()
							&& this.m_grunt_count >= 5)
				{
							proxyBot.research(unit.getUnitID(), ResearchType.HUMAN_SHIELD_2.getIdNum());
							m_research.add(ResearchType.HUMAN_SHIELD_2);
							
				}
				 
				else if(unit.getStatus()[0] == 0 
						&& m_research.contains(ResearchType.HUMAN_SWORD_2) == false
						&& m_research.contains(ResearchType.HUMAN_SWORD_1)
						&& proxyBot.getGold() > ResearchType.HUMAN_SWORD_2.getGoldCost()
						&& proxyBot.getWood() > ResearchType.HUMAN_SWORD_2.getWoodCost()
						&& this.m_grunt_count >= 5)
					{
						proxyBot.research(unit.getUnitID(), ResearchType.HUMAN_SWORD_2.getIdNum());
						m_research.add(ResearchType.HUMAN_SWORD_2);
						
					}
			}
			
			else if (unit.getTypeEnum() == UnitType.HUMAN_ELVEN_LUMBER_MILL
					|| unit.getTypeEnum() == UnitType.ORC_TROLL_LUMBER_MILL) {
				
				if(unit.getStatus()[0] == 0 
					&& m_research.contains(ResearchType.HUMAN_ARROW_1) == false 
					&& proxyBot.getGold() > ResearchType.HUMAN_ARROW_1.getGoldCost()
					&& proxyBot.getWood() > ResearchType.HUMAN_ARROW_1.getWoodCost()
					&& this.m_range_count >= 1)
				{
					proxyBot.research(unit.getUnitID(), ResearchType.HUMAN_ARROW_1.getIdNum());
					m_research.add(ResearchType.HUMAN_ARROW_1);
					
					/*
					for (ResearchType type : m_research)
					{
						System.out.println(type.name());
					}*/
					
				}
				
				else if(unit.getStatus()[0] == 0 
						&& m_research.contains(ResearchType.HUMAN_ARROW_2) == false
						&& m_research.contains(ResearchType.HUMAN_ARROW_1)
						&& proxyBot.getGold() > ResearchType.HUMAN_ARROW_2.getGoldCost()
						&& proxyBot.getWood() > ResearchType.HUMAN_ARROW_2.getWoodCost()
						&& this.m_range_count >= 5)
					{
						proxyBot.research(unit.getUnitID(), ResearchType.HUMAN_ARROW_2.getIdNum());
						m_research.add(ResearchType.HUMAN_ARROW_2);
						
					}
			}
		}
	}
	
	public void setPeonCount(int count) {
		m_peon_count = count;
	}

	public void setGruntCount(int count) {
		m_grunt_count = count;
	}
	
	public void setRangeCount(int count) {
		m_range_count = count;
	}
	
	public void setBarracksCount(int count) {
		barracksCount = count;
	}
	
	public void setBlackSmithCount(int count) {
		blacksmithCount = count;
	}
	
	public void setLumberMillCount(int count) {
		lumbermillCount = count;
	}
	
	public void setTowerCount(int count) {
		towerCount = count;
	}

}

